#pragma once
#include <zGraphicsConfig.hpp>
#include <Math/Vector3.hpp>
#include "Graphics.hpp"
#include <Image/Image.hpp>
#include "AABB.hpp"
#include "Color.hpp"

namespace zzz{
class ZGRAPHICS_CLASS GraphicsHelper {
public:
  inline void DrawLine(const Vector3d &p1, const Vector3d &p2) const
  {
    glBegin(GL_LINES);
    glVertex3dv(p1.Data());
    glVertex3dv(p2.Data());
    glEnd();
  }
  inline void DrawTriangle(const Vector3d &p1, const Vector3d &p2, const Vector3d &p3) const
  {
    glBegin(GL_TRIANGLES);
    glNormal3dv(p1.Data());
    glVertex3dv(p1.Data());
    glNormal3dv(p2.Data());
    glVertex3dv(p2.Data());
    glNormal3dv(p3.Data());
    glVertex3dv(p3.Data());
    glEnd();
  }
  void DrawPlane(const Vector3d &point, const Vector3d &normal, double size) const;
  void DrawGrid(const Vector3d &point, const Vector3d &normal, double size, double interval) const;
  void DrawCoord(const Vector3d &point, double length=10, int linewidth=4);
  void DrawSphere(const double r, const int levels) const;

  void DrawImage(const Image<Vector3f> &img)const{glDrawPixels(img.Cols(),img.Rows(),GL_RGB,GL_FLOAT,img.Data());}
  void DrawImage(const Image<Vector4f> &img)const{glDrawPixels(img.Cols(),img.Rows(),GL_RGBA,GL_FLOAT,img.Data());}
  void DrawImage(const Image<Vector3uc> &img)const{glDrawPixels(img.Cols(),img.Rows(),GL_RGB,GL_UNSIGNED_BYTE,img.Data());}
  void DrawImage(const Image<Vector4uc> &img)const{glDrawPixels(img.Cols(),img.Rows(),GL_RGBA,GL_UNSIGNED_BYTE,img.Data());}
  void DrawImage(const Image<zuchar> &img)const{glDrawPixels(img.Cols(),img.Rows(),GL_LUMINANCE,GL_UNSIGNED_BYTE,img.Data());}
  void DrawImage(const Image<float> &img)const{glDrawPixels(img.Cols(),img.Rows(),GL_LUMINANCE,GL_FLOAT,img.Data());}

  void DrawAABB(const AABB<3,float> &aabb, const Colorf& color, float width=1.0f) const;
private:
};

}